<template>
    <div class="file-upload">
        <a href="javascript:;" class="file" v-show="isRequesting===false">
            <slot></slot>
            <form enctype="multipart/form-data" method="post">
                <input type="file"
                       :name="name"
                       :id="id"
                       :multiple="multiple"
                       accept="image/jpg,image/jpeg,image/bmp,image/png,.pdf"
                       @click="fileInputClick"
                       @change="fileInputChange"
                       class="file-input">
            </form>
        </a>
        <button type="submit"
                class="file-waiting"
                disabled
                v-if="isRequesting===true">{{$t('common.waiting')}}...
        </button>
        <ul v-show="afterUpload.length > 0">
            <li v-for="file in afterUpload" class="uploaded-file">
                <i class="icon-attachment"></i>
                {{file.name.substr(0,file.name.lastIndexOf('.')).length>24?file.name.substr(0,24)+'...'+file.name.substring(file.name.lastIndexOf('.')):file.name}}
                &emsp;{{prettyBytes.format(file.size)}}
                <i class="icon-check" ></i>
                &emsp;<a href="javascript:;" @click="deleteFile(file)">{{$t('common.comp.upload.delete')}}</a>
            </li>
        </ul>
        <ul>
            <li v-for="(file,index) in previous.list" class="preload-file">
                <i class="icon-attachment"></i>
                {{file.name.substr(0,file.name.lastIndexOf('.')).length>24?file.name.substr(0,24)+'...'+file.name.substring(file.name.lastIndexOf('.')):file.name}}
                &emsp;{{prettyBytes.format(file.size)}}
                <div class="progress-bar-wrap">
                    <div class="progress-bar" :style="{width:file.progress+'%'}"></div>
                </div>
            </li>
        </ul>
    </div>


</template>

<script type="text/babel">
    import prettyBytes from './vue.pretty-bytes';
    import cookie from '../../util/cookie';
    export default {
        props: {
            clazz: String,
            name: {
                type: String
            },
            id: String,
            action: {
                type: String
            },
            accept: {
                type: String,
                default: 'image/*'
            },
            multiple: String,
            headers: Object,
            method: String,
            buttonText: {
                type: String,
                default: '↑Upload'
            },
            maxSize: {
                default: 2048
            },
            errTip:{
                default: ''
            }
        },
        data: function () {
            return {
                myFiles: [],
                prettyBytes:prettyBytes,
                isRequesting:false,
                previous: {
                    list: []
                },
                afterUpload: [],
                uploadFileList:[]
            };
        },
        methods: {
            fileInputClick: function () {
                this.$emit('onFileClick', this.id);
                let ident = this.id || this.name;
                let files = document.getElementById(ident).files;
//                document.getElementById(ident).type = "text";
//                document.getElementById(ident).type = "file";

                for (let i = 0; i < files.length; i++) {
                    //超出大小
                    if (files[i].size / 1024 > this.maxSize) {
                        document.getElementById(ident).type = "text";
                        document.getElementById(ident).type = "file";
                        return;
                    }
                }

            },


            fileInputChange: function () {
                let ident = this.id || this.name;
                this.myFiles = document.getElementById(ident).files;

                //一次性选择超过5个
                if (this.myFiles.length > 5) {
                    window.error(this.$t('common.comp.upload.fivefiles'));//'You can choose at most five files, please retry.'
                    this.myFiles = [];
                    return false;
                }
                //检查每一个文件的大小、类型
                for (let i = 0; i < this.myFiles.length; i++) {
                    // 超出大小
                    if (this.myFiles[i].size / 1024 > this.maxSize) {
                        window.error(this.$t('common.comp.upload.outofsize',{size:this.maxSize}));//'Out of size ' + this.maxSize + 'kb, please retry.'
                        this.myFiles = [];
                        return false;
                    }
                    //  类型
                    if(this.myFiles[i].type.indexOf('image')<0&&this.myFiles[i].type.toUpperCase().indexOf('PDF')<0){
                        window.error(this.$t('common.comp.upload.errtype'));//'Error type, please retry.'
                        return false;
                    }
                }

                //必须有选择文件才触发
                if(this.myFiles.length>0){
                    //如果不是多选，清空已经上传的文件
                    if(this.multiple===undefined){
                        this.afterUpload = [];
                        this.uploadFileList = [];
                    }
                    this.previous.list = Array.prototype.slice.call(this.myFiles, 0).map(function (file) {
                        return {
                            name: file.name,
                            size: file.size,
                            progress: 0
                        };
                    });
                    //总共文件个数
                    if ((this.previous.list.length + this.afterUpload.length) > 5) {
                        window.error(this.$t('common.comp.upload.fivefiles'));//'You can choose at most five files, please retry.'
                        this.previous.list = [];
                    }else{
                        this.fileUpload();
                    }
                }
            },


            _handleUpload: function (file) {
                this.$emit('beforeFileUpload', file);
                let form = new FormData();
                let xhr = new XMLHttpRequest();
                try {
                    form.append('Content-Type', file.type || 'application/octet-stream');
                    form.append('file', file);
                } catch (err) {
                    this.onFileError(file, err);
                    return;
                }

                return $.Deferred(function (deferred) {
                    xhr.upload.addEventListener('progress', function (e) {
                        e.percent = (e.loaded / e.total) * 100;
                        console.log('onFileProgress', e);
                        let progressFile = _.find(this.previous.list, function (currentFile) {
                            return currentFile.name == file.name;
                        })
                        progressFile.progress = e.percent;
                    }.bind(this), false);

                    xhr.onreadystatechange = function () {
                        if (xhr.readyState < 4) {
                            return;
                        }
                        if (xhr.status == 200) {
                            let res = JSON.parse(xhr.responseText);
                            if(res.code&&res.code!='100200'){
                                let err = this.$t('common.comp.upload.err');//'File upload error.';
                                this.onFileError(file, err);
                                deferred.reject(err);
                            }else{
                                this.onFileUpload(file,res);
                                deferred.resolve(file);
                            }

                        } else {
                            let err = this.$t('common.comp.upload.err');
                            this.onFileError(file, err);
                            deferred.reject(err);
                        }
                    }.bind(this);

                    xhr.onerror = function () {
                        let err = JSON.parse(xhr.responseText);
                        err.status = xhr.status;
                        err.statusText = xhr.statusText;
                        this.onFileError(file, err);
                        deferred.reject(err);
                    }.bind(this);

                    xhr.open(this.method || "POST", this.action, true);
                    if (this.headers) {
                        for (let header in this.headers) {
                            xhr.setRequestHeader(header, this.headers[header]);
                        }
                    }
                    let loginToken = cookie.get('LOGIN_TOKEN');
                    xhr.setRequestHeader('authorization','token=' + loginToken);
                    xhr.send(form);
                    this.isRequesting = true;
                }.bind(this));
            },


            fileUpload: function () {
                if (this.myFiles.length > 0) {
                    let arrayOfPromises = Array.prototype.slice.call(this.myFiles, 0).map(function (file) {
                        return this._handleUpload(file);
                    }.bind(this));

                    $.when(arrayOfPromises).done(function (allFiles) {
                        this.myFiles = [];
                    }.bind(this)).catch(function (err) {
                        this.onFileError(file, err);
                    }.bind(this));
                } else {
                }
            },


            deleteFile(file){
                this.uploadFileList = _.without(this.uploadFileList, file.url);
                this.afterUpload = _.without(this.afterUpload, file);
                this.$emit('deleteFile', this.uploadFileList,this.id);
                window.success(this.$t('common.comp.upload.deleteSuccess'));

                let ident = this.id || this.name;
                document.getElementById(ident).type = "text";
                document.getElementById(ident).type = "file";

            },


            onFileError: function (file, res) {
                _.remove(this.previous.list, function (currentFile) {
                    return currentFile.name == file.name;
                });
                let ident = this.id || this.name;
                document.getElementById(ident).type = "text";
                document.getElementById(ident).type = "file";
                this.isRequesting=false;
                window.error(res);
                console.error('onFileError', file, res);
            },


            onFileUpload: function (file, res) {
                _.remove(this.previous.list, function (currentFile) {
                    return currentFile.name == file.name;
                });
                let url = res.data.name;
                this.uploadFileList.push(url);
                this.afterUpload.push({
                    url: url,
                    size:file.size,
                    name: file.name
                });
                this.isRequesting=false;
                this.$emit('onFileUpload', this.uploadFileList,this.id);
            },
        }
    }
</script>

<style lang="sass" rel="stylesheet/scss">
    .file-upload {
        .file {
            position: relative;
            display: inline-block;
            background: #1e97fc;
            padding: 6px 12px;
            overflow: hidden;
            color: #ffffff;
            text-decoration: none;
            text-indent: 0;
            line-height: 22px;
            /*border-radius: 15px;*/
        }
        .file input {
            position: absolute;
            font-size: 0;
            width: 80px;
            right: 0;
            top: 0;
            cursor: pointer;
            opacity: 0;
        }
        .file:hover {
            background: #2399fb;
            text-decoration: none;
        }

    }
    .upload-btn {
        border-radius: 20px;
        line-height: 30px;
        height: 30px;
        margin-top: 16px;
    }
    .file-input {
        height: 30px;
        line-height: 30px;
        font-size: 12px;
    }

    .progress-bar-wrap {
        width: 200px;
        height: 2px;
        background-color: #eaeaea;
    }
    .progress-bar {
        opacity: 1;
        height: 2px;
        width: 0;
        background: #1e97fc;
    }

    .file-error {
        color: #f9504b;
        font-size: 12px;
    }

    .uploaded-file {
        line-height: 30px;
        font-size: 12px;
        color: #999;
    }

    .preload-file {
        line-height: 28px;
        font-size: 12px;
        color: #999;
    }

    .icon-attachment {
        color: #999;
    }
    .icon-check {
        color: #2399fb;
        font-size: 13px;
        font-weight: bold;

    }
    .file-container{
        margin-top: 12px;
        width: 400px;
    }
    .file-waiting{
        position: relative;
        display: inline-block;
        background: rgba(30, 151, 252, 0.8);
        border: 1px solid #1e97fc;
        padding: 6px 12px;
        overflow: hidden;
        color: #ffffff;
        text-decoration: none;
        text-indent: 0;
        line-height: 20px;
        width: 85px;
    }
    .ui-tip{
        color: #f9504b;
    }
</style>